/*************************************************************************
 * 文件名称: cvcamera.h
 * 创建姓名: 唐文杰
 * 作   用: 用于获取摄像头的视频流中的帧画面并返回（子线程中执行）
 ***************************************************************************/

#ifndef CVCAMERA_H
#define CVCAMERA_H

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>

#include <QWidget>
#include <QCameraInfo>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QTimer>
#include <QStringList>
#include <QImage>
#include <QPixmap>

#include "DebugPrint/myDebugPrint.h"
#include "ENUM/enum.h"
#include "XML/XmlFunc.h"

using namespace cv;

//创建一个子线程（专门用于捕获摄像头中视频流的帧画面）
class CVCamera : public QThread
{
    Q_OBJECT
public:

    /**
     @param  fps 设置当前从摄像头视频流中每隔多少毫秒获取一次帧画面（相当于帧率,默认33帧）
     @return
     */
    CVCamera(int fps = 33);

    /**
     @说明 用于设置该类中各种参数
     @param gamma   当前将当前伽马数值更改为gamma大小
     @param lum     将当前亮度修改为lum大小
     @param comp    将当前对比度修改为comp大小
     @param chroma  将当前饱和度修改为chroma大小
     @param fps     将当前视频帧率修改为fps大小（所有参数传入-1均表示采用当前数据不做更新）
     @return true-成功;false-失败
     */
    bool setImgSetting(const double gamma, const double lum, const double comp, const double chroma, const int fps);

    /**
     @说明   对QThread的run方法进行重写构成多态
     */
    void run() override;

    /**
     @interpret 打开对应索引的摄像头
     @param     index 设置当前需要打开摄像头的索引
     @return    true-成功;false-失败
     */
    bool openCamera(int index);

    /**
     @interpret 修改对应画面的伽马值
     @param     img 需要设置伽马值的图像
     @param     gamma 需要修改到的伽马值
     @return    true-成功;false-失败
     */
     bool setMatGamma(Mat& img, const double gamma);

     /**
     @interpret （简单）修改对应画面的lian高度
     @param     img 需要修改亮度的图像
     @param     lum 需要修改的亮度值
     @return    true-成功;false-失败
     */
     bool setLum(Mat& img, const double lum);

     /**
     @interpret 通过调用对应方法修改图像对比度
     @param     img 需要修改亮度的图像
     @param     comp 需要修改的对比度
     @return    true-成功;false-失败
     */
     bool setComp(Mat& img, const double comp);

     /**
     @interpret 修改图像饱和度
     @param     img 需要修改亮度的图像
     @param     chroma 需要修改的饱和度
     @return    true-成功;false-失败
     */
     bool setChroma(Mat& img, const double chroma);

     /**
     @interpret 修改曝光时长
     @param     value 将要修改的时长
     @return    true-成功;false-失败
     */
     bool setExposureNum(int value);

     /**
     @interpret 修改增益数值
     @param     value 将要修改的值
     @return    true-成功;false-失败
     */
     bool setBufferNum(int value);

     /**
     @interpret 设置是否录制视频
     @param     btn: 表示当前是否录制视频
     @return    无
     */
     void setRecordVideo(btnStatus btn);

     /**
     @interpret 获取当前图片
     @param     无
     @return    无
     */
     void GetImage();

     /**
     @interpret 开启视频追踪
     @param     无
     @return    无
     */
     void OpenVideoTrack(bool isTrack);

     /**
     @interpret 对图片进行CamShift算法处理
     @param     无
     @return    无
     */
     void MyCamShift();
signals:
    /**
    @interpret 发送传输图片信号
    @param     无
    @return    无
    */
     void senderPixmap(const QPixmap&);
private slots:
    
private:

    Mat    m_CurrentImg;              // 用于表示当前画面图像
    QTimer*m_GetMat;                  // 用于设置定时器，在规定时间内获取帧画面
    int    m_CurrentCameraIndex=-1;   // 用于表示当前选择摄像头的索引
    int    m_VideoFPS;                // 用于表示视频帧率（每隔一定时间就从视频流中获取一帧画面）
    double m_Gamma = 1.0;             // 用于表示当前伽马值
    double m_Lum = 1.0;               // 用于表示当前亮度
    double m_Comp = 1.0;              // 用于表示当前对比度
    double m_Chroma = 0;              // 用于表示当前画面的饱和度
    int    m_Exposure = 10;           // 当前曝光时长默认10ms;

    CameraStatus  m_IsRecord;         // 是否开启录制
    VideoCapture* m_apture;           // 用于从视频流中捕获帧画面
    QMutex        m_Mutex;            // 保证主线程获取帧画面时线程安全
    QStringList   m_CameraS;          // 保存当前系统所有摄像头的名称，后期方便主线程检索
    QPixmap       m_CurrentPixmap;    // 表示当前图像转换的图片
    VideoWriter   m_Video;            // 保存当前捕获视频
    QString       m_VideoImagePath;   // 存储当前视频/图片需要存储的位置
    btnStatus     m_VideoIsTrack;     // 记录当前是否开启视频追踪模式
    Mat           m_Histogram;        // 作为追踪时的模板直方图(后面查找就是依靠该直方图进行查找)
    Rect          m_Selection;        // 搜索模板的尺寸
};

#endif // CVCAMERA_H
